#include "pub_aliyun_thread.h"
#include "mqtt_dev/mqtt_dev.h"
#include <QString>
#include <cstring>
#include <QMutex>
#include "set_aliyun_link_dialog.h"
#include <QDebug>
#include <iostream>

using namespace std;

extern volatile bool pcf8591_dev_discon;
extern volatile bool net_is_con;

pub_aliyun_thread::pub_aliyun_thread()
{
    this->msg = MQTTClient_message_initializer;
}

pub_aliyun_thread::pub_aliyun_thread(MQTTClient *client,dtu_4G *dtu_4g_dev)
{
    qRegisterMetaType<gather_data>("gather_data");  //注册gather_data类型
    this->clent = client;
    this->dtu_4g_dev = dtu_4g_dev;
    this->msg = MQTTClient_message_initializer;
    this->ads1115_dev = new ads1115(this,const_cast<char*>("/dev/i2c-0"),0x48);
    this->humiture_dev = new rs485_dev(static_cast<QString>("ttyS1"),this);
    //关联信号与槽
    connect(this->humiture_dev,&rs485_dev::newValue,this,&pub_aliyun_thread::get_humiture);
    connect(this,&pub_aliyun_thread::humiture_dev_send_signal,this,&pub_aliyun_thread::huimture_dev_send_slots);
}

pub_aliyun_thread::~pub_aliyun_thread()
{

}

void pub_aliyun_thread::setCache_data_size_max(const qint16 &value)
{
    cache_data_size_max = value;
}

/* 获取电压值 */
float pub_aliyun_thread::get_voltage()
{
    unsigned char write_buf[2]{};
    unsigned char read_buf[2]{};

    write_buf[0] = 0x42;
    write_buf[1] = 0x83;
    this->ads1115_dev->write_data(0x01,write_buf,2);
    unsigned short voltage_original = 0;
    this->ads1115_dev->read_data(0x00,read_buf,2);
    voltage_original = read_buf[0];
    voltage_original = (voltage_original << 8) + read_buf[1];
    float voltage = (float)voltage_original / 32768 * 4.096;

    return voltage;
}

/* 获取电流值 */
float pub_aliyun_thread::get_electricity()
{
    float electricity = 0.0f;

    return electricity;
}

/* 当网络断开时进行离线数据缓存 */
void pub_aliyun_thread::cache_data()
{
    struct gather_data tmp = this->data;
    this->cache_vessel.push_back(tmp);
    if(this->cache_vessel.size() >= this->cache_data_size_max)
    {
        this->cache_vessel.pop_front();
    }
}

/* 获取温湿度 */
void pub_aliyun_thread::get_humiture(QByteArray val)
{
    quint16 tmp = 0;
    qint8 start_index = 0;

    if(rs485_dev::recv_data_bit_len == 8)
    {
        start_index = 2;
    }
    else if(rs485_dev::recv_data_bit_len == 9)
    {
        start_index = 3;
    }
    this->is_get_humiture = true;
    if(rs485_dev::recv_cnt == 2 || rs485_dev::recv_data_bit_len == 9)
    {
        tmp |= (unsigned char)val[start_index++];
        tmp = (tmp << 8) | (unsigned char)val[start_index++];
        this->data.humiture[temp] = static_cast<float>(tmp) * 0.1;
        tmp = 0;
        tmp |= (unsigned char)val[start_index++];
        tmp = (tmp << 8) | (unsigned char)val[start_index++];
        this->data.humiture[humidity] = static_cast<float>(tmp) * 0.1;
        this->humiture_dev->read_buf_clear();
        if(rs485_dev::recv_cnt == 2)
            rs485_dev::recv_cnt = 0;
        if(rs485_dev::recv_data_bit_len == 9)
            rs485_dev::recv_data_bit_len = 0;
    }
}

void pub_aliyun_thread::huimture_dev_send_slots()
{
    QByteArray write_buf{};
    write_buf[0] = 0x01;
    write_buf[1] = 0x04;
    write_buf[2] = 0x00;
    write_buf[3] = 0x00;
    write_buf[4] = 0x00;
    write_buf[5] = 0x02;
    write_buf[6] = 0x71;
    write_buf[7] = 0xCB;
    this->humiture_dev->write_data(write_buf);
}

/**
  @description:子线程run函数
*/
void pub_aliyun_thread::run()
{
    this->data_get = true;
    this->is_pub_date = true;
    int rc = -1;
    while (this->data_get)
    {
        /* 数据上传条件：采集到新数据、网络正常连接和连接到云平台 */
        if(this->is_pub_date)
        {
            this->data.voltage = this->get_voltage();
            if(this->is_get_humiture)
            {
                /* 以太网方式进行数据上传 */
                if(set_aliyun_link_dialog::getAly_link_mode() == set_aliyun_link_dialog::Ethernet_mode)
                {
                    if(net_is_con && !pcf8591_dev_discon)
                    {
                        char * ident = const_cast<char*>("voltage");
                        char *cstr = NULL;
                        cstr = DATA_DEV_PUB_DATA(ident,this->data.voltage);
                        this->msg.qos = 0;
                        this->msg.retained = 1;
                        if((rc = MQTTClient_publishMessage(*this->clent,DATA_DEV_PUB_TOPIC,&this->msg,NULL)) != MQTTCLIENT_SUCCESS)
                        {
                            printf("%s data pub failed\n",ident);
                        }
                        ident = const_cast<char*>("CurrentTemperature");
                        cstr = DATA_DEV_PUB_DATA(ident,this->data.humiture[temp]);
                        this->msg.payload = cstr;
                        this->msg.payloadlen = strlen(cstr);
                        if((rc = MQTTClient_publishMessage(*this->clent,DATA_DEV_PUB_TOPIC,&this->msg,NULL)) != MQTTCLIENT_SUCCESS)
                        {
                            printf("%s data pub failed\n",ident);
                        }
                        ident = const_cast<char*>("Humidity");
                        cstr = DATA_DEV_PUB_DATA(ident,this->data.humiture[humidity]);
                        this->msg.payload = cstr;
                        this->msg.payloadlen = strlen(cstr);
                        if((rc = MQTTClient_publishMessage(*this->clent,DATA_DEV_PUB_TOPIC,&this->msg,NULL)) != MQTTCLIENT_SUCCESS)
                        {
                            printf("%s data pub failed\n",ident);
                        }
                    }
                }
                /* 4GDTU方式进行数据上传 */
                else if(set_aliyun_link_dialog::getAly_link_mode() == set_aliyun_link_dialog::dtu_4G_mode)
                {
                    static qint8 cnt = 0;
                    if(!pcf8591_dev_discon)
                    {
                        if(cnt < 4)
                        {
                            cnt++;
                        }
                        else
                        {
                            char * ident = const_cast<char*>("voltage");
                            char *mes = DATA_DEV_PUB_DATA(ident,this->data.voltage);
                            this->dtu_4g_dev->aliyun_serianet_pub_mes(static_cast<const char*>(mes));
                            ident = const_cast<char*>("CurrentTemperature");
                            mes = DATA_DEV_PUB_DATA(ident,this->data.humiture[temp]);
                            this->dtu_4g_dev->aliyun_serianet_pub_mes(static_cast<const char*>(mes));
                            ident = const_cast<char*>("Humidity");
                            mes = DATA_DEV_PUB_DATA(ident,this->data.humiture[humidity]);
                            this->dtu_4g_dev->aliyun_serianet_pub_mes(static_cast<const char*>(mes));
                        }
                    }
                }
                /* NB-iot方式进行数据上传 */
                else if(set_aliyun_link_dialog::getAly_link_mode() == set_aliyun_link_dialog::nb_iot_mode)
                {
                }
            }
            this->is_get_humiture = false;
            emit humiture_dev_send_signal();
            emit get_data_ok(this->data);
        }
        if(!net_is_con)    //当网关离线时进行数据存储
        {
            this->cache_data();
        }
        sleep(1);
    }
}

void pub_aliyun_thread::set_get_data_state(bool newState)
{
    this->data_get = newState;
}

void pub_aliyun_thread::set_is_pub_date(bool state)
{
    this->is_pub_date = state;
}
